from flask import Flask, render_template, request, jsonify, make_response
from flask_sqlalchemy import SQLAlchemy
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity
import os
from datetime import datetime

app = Flask(__name__)
# 其他配置和数据库模型定义...

@app.route('/')
def index():
    return render_template('index.html')

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:87654321@127.0.0.1:3306/shareexcel'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['JWT_SECRET_KEY'] = b'N\xc9 \xa3\xd7\xae \x1b\xd4\xcc>\x06<\n\xd8Y\r\xf1\xb2\xaf\x9a\x9c<\xf2'
app.config['JWT_TOKEN_LOCATION'] = ['headers']

db = SQLAlchemy(app)
jwt = JWTManager(app)


class ExcelUser(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    password = db.Column(db.String(120), nullable=False)


class ExcelDocument(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    created_by = db.Column(db.Integer, nullable=False)
    locked_by = db.Column(db.Integer)
    is_locked = db.Column(db.Boolean, default=False)


class ExcelDocumentVersion(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    version = db.Column(db.Integer, nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    created_by = db.Column(db.Integer, nullable=False)
    document_id = db.Column(db.Integer, nullable=False)
    content = db.Column(db.Text, nullable=False)


@app.route('/api/register', methods=['POST'])
def register():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')

    if not username or not password:
        return jsonify({"message": "用户名和密码是必需的"}), 400

    if ExcelUser.query.filter_by(username=username).first():
        return jsonify({"message": "用户名已存在"}), 400

    new_user = ExcelUser(username=username, password=password)
    db.session.add(new_user)
    db.session.commit()

    return jsonify({"message": "注册成功"}), 201


@app.route('/api/login', methods=['POST'])
def login():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')

    user = ExcelUser.query.filter_by(username=username, password=password).first()

    if user:
        access_token = create_access_token(identity=str(user.id))
        return jsonify({"token": access_token}), 200
    else:
        return jsonify({"message": "用户名或密码错误"}), 401


@app.route('/api/me', methods=['GET'])
@jwt_required()
def get_current_user():
    try:
        user_id = get_jwt_identity()
        user = ExcelUser.query.get(user_id)
        if user:
            return jsonify({"id": user.id, "username": user.username}), 200
        else:
            return jsonify({"message": "用户未找到"}), 404
    except Exception as e:
        print(e)
        return jsonify({"message": str(e)}), 500

# 加载文档列表
@app.route('/api/docs', methods=['GET'])
@jwt_required()
def get_documents():
    user_id = get_jwt_identity()
    documents = ExcelDocument.query.filter_by(created_by=user_id).all()
    doc_list = []
    for doc in documents:
        doc_list.append({
            "id": doc.id,
            "title": doc.title,
            "created_at": doc.created_at
        })
    return jsonify(doc_list), 200

# 创建文档
@app.route('/api/docs', methods=['POST'])
@jwt_required()
def create_document():
    user_id = get_jwt_identity()
    data = request.get_json()
    title = data.get('title')

    if not title:
        return jsonify({"message": "文档标题是必需的"}), 400

    new_doc = ExcelDocument(title=title, created_by=user_id)
    db.session.add(new_doc)
    db.session.commit()

    return jsonify({
        "id": new_doc.id,
        "title": new_doc.title,
        "created_at": new_doc.created_at
    }), 201


@app.route('/api/docs/<int:doc_id>', methods=['GET'])
@jwt_required()
def get_document(doc_id):
    user_id = get_jwt_identity()
    doc = ExcelDocument.query.filter_by(id=doc_id, created_by=user_id).first()
    if doc:
        latest_version = ExcelDocumentVersion.query.filter_by(
            document_id=doc_id).order_by(ExcelDocumentVersion.version.desc()).first()
        if latest_version:
            content = latest_version.content
        else:
            content = []
        return jsonify({"content": content}), 200
    else:
        return jsonify({"message": "文档未找到"}), 404


@app.route('/api/docs/<int:doc_id>/versions', methods=['POST'])
@jwt_required()
def save_version(doc_id):
    user_id = get_jwt_identity()
    doc = ExcelDocument.query.filter_by(id=doc_id, created_by=user_id).first()
    if doc:
        if not doc.is_locked or doc.locked_by != user_id:
            return jsonify({"message": "你没有编辑权限"}), 403
        data = request.get_json()
        content = data.get('content')
        latest_version = ExcelDocumentVersion.query.filter_by(
            document_id=doc_id).order_by(ExcelDocumentVersion.version.desc()).first()
        new_version = latest_version.version + 1 if latest_version else 1
        new_doc_version = ExcelDocumentVersion(
            version=new_version,
            created_by=user_id,
            document_id=doc_id,
            content=str(content)
        )
        db.session.add(new_doc_version)
        db.session.commit()
        return jsonify({"message": "版本保存成功"}), 201
    else:
        return jsonify({"message": "文档未找到"}), 404


@app.route('/api/docs/<int:doc_id>/lock', methods=['POST'])
@jwt_required()
def request_lock(doc_id):
    user_id = get_jwt_identity()
    doc = ExcelDocument.query.filter_by(id=doc_id).first()
    if doc:
        if doc.is_locked:
            return jsonify({"message": "文档已被锁定"}), 403
        doc.is_locked = True
        doc.locked_by = user_id
        db.session.commit()
        return jsonify({"message": "成功获取编辑权限"}), 200
    else:
        return jsonify({"message": "文档未找到"}), 404


@app.route('/api/docs/<int:doc_id>/lock-status', methods=['GET'])
@jwt_required()
def get_lock_status(doc_id):
    doc = ExcelDocument.query.filter_by(id=doc_id).first()
    if doc:
        locked_by = ExcelUser.query.get(doc.locked_by) if doc.locked_by else None
        return jsonify({
            "is_locked": doc.is_locked,
            "locked_by": locked_by.username if locked_by else None
        }), 200
    else:
        return jsonify({"message": "文档未找到"}), 404


@app.route('/api/docs/<int:doc_id>/versions', methods=['GET'])
@jwt_required()
def get_versions(doc_id):
    user_id = get_jwt_identity()
    doc = ExcelDocument.query.filter_by(id=doc_id, created_by=user_id).first()
    if doc:
        versions = ExcelDocumentVersion.query.filter_by(
            document_id=doc_id).order_by(ExcelDocumentVersion.version.desc()).all()
        version_list = []
        for version in versions:
            user = ExcelUser.query.get(version.created_by)
            version_list.append({
                "version": version.version,
                "created_at": version.created_at,
                "created_by": {"username": user.username}
            })
        return jsonify(version_list), 200
    else:
        return jsonify({"message": "文档未找到"}), 404


if __name__ == '__main__':
    with app.app_context():
        db.create_all()
    app.run(debug=True)
    